<script setup lang="ts">
import { getCurrentInstance, reactive, nextTick } from 'vue'
import { pinyin } from 'pinyin-pro'
const { proxy } = getCurrentInstance()

/* ---- */
const slide = reactive({
  isFirst: true,
  show: false,
  shade: false,
  box: false,
  rotate: false,
  // ----
  type: 0,
  forall: { show: false, text: '' },
  boxTop: {},
  slideName: '',
  boxClass: '',
  floatClass: 'xw-float-W1',
  itemId: -1,
  itemName: '',
  childName: '',
  title: '',
  align: {},
  list: [],
  callback: '',
  // ----
  noData: proxy.$Global.noData,
  isSearch: false,
  infoSch: '',
  changeTop: 0,
  isLetter: /^([A-Z]+)$/,
  sortItems: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '#'],
  sortTops: [],
  items: [],
  // ----
  spaceback: '',
  areaback: []
})

/* ---- */
const open = (opt) => {
  if (opt) {
    for (const key in opt) { slide[key] = opt[key] }
  }
  slide.show = true
  // ----
  switch (Number(slide.type)) {
    case 4: {
      setSlideData(slide.isFirst, slide.list, (res) => {
        if (res && Number(res.length) > 0) slide.items = res
        // ----
        nextTick(() => {
          slide.shade = true
          slide.box = true
          nextTick(() => {
            slide.changeTop = document.querySelector('.SLB-boxp-top').offsetHeight
            // ----
            slide.items.forEach((item, index) => {
              slide.sortTops.push(document.querySelector('.scBox_' + index).offsetTop)
            })
          })
        })
      })
      break
    }
    default: {
      nextTick(() => {
        slide.shade = true
        slide.box = true
      })
    }
  }
}
const setSlideData = async (isInit, items, callback) => {
  let newItems = []
  if (isInit) {
    const forItems = []
    await slide.sortItems.forEach((item) => {
      forItems.push({
        letter: item,
        children: []
      })
    })
    // ----
    await items.forEach((item) => {
      let forLetter = proxy.$Myfun.setText(item.text).slice(0, 1)
      forLetter = pinyin(forLetter, { pattern: 'first', toneType: 'none' }).toUpperCase()
      if (!slide.isLetter.test(forLetter)) forLetter = '#'
      // ----
      forItems.forEach((curItem) => {
        if (String(curItem.letter) === String(forLetter)) curItem.children.push(item)
      })
    })
    // ----
    newItems = forItems.filter((item) => { return Number(item.children.length) > 0 })
  }
  // ----
  callback && callback(newItems)
}
const close = () => {
  slide.isFirst = false
  slide.shade = false
  slide.box = false
  // ----
  slide.forall = { show: false, text: '' }
  slide.floatClass = 'xw-float-W1'
  slide.itemId = -1
  slide.itemName = ''
  slide.childName = ''
  // ----
  slide.isSearch = false
  slide.sortTops = []
  // ----
  setTimeout(() => { slide.show = false }, 300)
  // ----
  slide.spaceback && slide.spaceback()
}
const showChild = (event) => {
  const el = event.target
  const forEm = el.querySelector('em')
  const forDL = el.parentElement.querySelector('dl')
  if (forEm.classList.contains('iconDown')) {
    forEm.classList.remove('iconDown')
    forEm.classList.add('iconUp')
    // ----
    forDL.style.display = 'block'
  } else {
    forEm.classList.remove('iconUp')
    forEm.classList.add('iconDown')
    // ----
    forDL.style.display = 'none'
  }
}
const isCheck = (event, item, son) => {
  const el = event.currentTarget
  let sertIndex = -1
  let tsonIndex = -1
  let someIndex = 0
  let newItems = {}
  const newItemson = {
    value: son.value,
    text: son.text
  }
  // ----
  const result = slide.areaback.some((current, index) => {
    if (Number(current.value) === Number(item.value)) {
      someIndex = index
      return true
    }
    if (Number(item.value) > Number(current.value)) sertIndex = index + 1
  })
  // ----
  if (el.classList.contains('active')) {
    el.classList.remove('active')
    // ----
    let delIndex = 0
    for (let i = 0; i < slide.areaback[someIndex].children.length; i++) {
      if (Number(slide.areaback[someIndex].children[i].value) === Number(son.value)) {
        delIndex = i
        break
      }
    }
    slide.areaback[someIndex].children.splice(delIndex, 1)
    if (Number(slide.areaback[someIndex].children.length) === 0) {
      slide.areaback.splice(someIndex, 1)
    }
  } else {
    el.classList.add('active')
    // ----
    if (result) {
      slide.areaback[someIndex].children.some((current, index) => {
        if (Number(son.value) > Number(current.value)) tsonIndex = index + 1
      })
      if (Number(tsonIndex) === Number(-1)) {
        slide.areaback[someIndex].children.splice(0, 0, newItemson)
      } else if (Number(tsonIndex) === Number(slide.areaback[someIndex].children.length)) {
        slide.areaback[someIndex].children.push({})
        slide.areaback[someIndex].children.splice(tsonIndex, 1, newItemson)
      } else {
        slide.areaback[someIndex].children.splice(tsonIndex, 0, newItemson)
      }
    } else {
      newItems = {
        value: item.value,
        text: item.text,
        children: [newItemson]
      }
      if (Number(slide.areaback.length) === 0 || Number(sertIndex) === Number(-1)) {
        slide.areaback.splice(0, 0, newItems)
      } else if (Number(sertIndex) === Number(slide.areaback.length)) {
        slide.areaback.push({})
        slide.areaback.splice(sertIndex, 1, newItems)
      } else {
        slide.areaback.splice(sertIndex, 0, newItems)
      }
    }
  }
  // ----
  nextTick(() => { slide.callback && slide.callback(slide.areaback) })
}
const emptyInfo = (event) => {
  const curEL = event.currentTarget
  const input = curEL.parentElement.querySelector('input')
  input.value = ''
  input.dispatchEvent(new Event('input'))
  // ----
  getAuditFun(1)
}
const getAuditFun = (type, item) => {
  switch (Number(type)) {
    case 1: {
      const theEls = document.querySelectorAll('.SLB-piny a')
      theEls.forEach((curItem) => { curItem.classList.remove('active') })
      // ----
      const newItems = slide.list.filter((curItem) => { return Number(curItem.text.indexOf(slide.infoSch)) !== Number(-1) })
      // ----
      setSlideData(true, newItems, (res) => {
        slide.items = res
        // ----
        slide.sortTops = []
        nextTick(() => {
          slide.items.forEach((curItem, index) => {
            slide.sortTops.push(document.querySelector('.scBox_' + index).offsetTop)
          })
        })
      })
      break
    }
  }
}
const forScrollTo = (theObj, index) => {
  const theEls = document.querySelectorAll(theObj)
  theEls.forEach((item, curIndex) => {
    if (Number(curIndex) === Number(index)) {
      item.classList.add('active')
    } else {
      item.classList.remove('active')
    }
  })
}
const forScrollAct = (theObj, num) => {
  const len = slide.sortTops.length
  let forIndex = -1
  slide.sortTops.forEach((item, index) => {
    if (Number(index) < Number(len - 1)) {
      if (Number(item) < num && num < Number(slide.sortTops[index + 1])) forIndex = index
    } else if (Number(index) === Number(len - 1)) {
      if (Number(item) < num) forIndex = index
    }
  })
  // ----
  const theEls = document.querySelectorAll(theObj)
  theEls.forEach((item, index) => {
    if (Number(index) === Number(forIndex)) {
      item.classList.add('active')
    } else {
      item.classList.remove('active')
    }
  })
}
const refreshInfo = (info) => {
  close()
  slide.callback && slide.callback(info)
}

/* ---- */
defineExpose({
  open
})
</script>

<template>
  <div class="mescroll-touch slideBox" v-if="slide.show">
    <transition name="fade">
      <div class="mask" v-if="slide.shade" @click="close"></div>
    </transition>
    <transition :name="slide.slideName" v-if="Number(slide.type) === 0">
      <div :class="['SLB-box', slide.boxClass]" v-if="slide.box">
        <div class="SLB-title">{{slide.title}}</div>
        <ul class="SLB-list xw-flex xw-flex-column" v-if="Number(slide.itemId) >= 0">
          <li v-if="slide.forall.show">
            <dl>
              <dd :class="['xw-ellipsis xw-Tfg', Number(slide.itemId) === 0 ? 'active' : '']" @click="refreshInfo">{{slide.forall.text}}</dd>
            </dl>
          </li>
          <li v-for="(item, index) in slide.list">
            <dl>
              <dd :class="['xw-Tfg xw-flex xw-flex-align', Number(item.value) === Number(slide.itemId) ? 'active' : '']" @click="refreshInfo([item.text, item.value])">
                <div class="SLB-icon" v-if="item.icon"><div class="xw-bgImg" :style="{ backgroundImage: 'url(' + item.icon + ')' }"></div></div>
                <span class="xw-flex-W1 xw-ellipsis">{{item.text}}</span>
              </dd>
            </dl>
          </li>
        </ul>
        <ul class="SLB-list xw-flex xw-flex-column" v-else >
          <li v-if="slide.forall.show">
            <dl>
              <dd :class="['xw-ellipsis xw-Tfg', String(slide.itemName) === '' ? 'active' : '']" @click="refreshInfo">{{slide.forall.text}}</dd>
            </dl>
          </li>
          <li v-for="(item, index) in slide.list">
            <dl>
              <dd :class="['xw-Tfg xw-flex xw-flex-align', String(item.text) === String(slide.itemName) ? 'active' : '']" @click="refreshInfo([item.text, item.value])">
                <div class="SLB-icon" v-if="item.icon"><div class="xw-bgImg" :style="{ backgroundImage: 'url(' + item.icon + ')' }"></div></div>
                <span class="xw-flex-W1 xw-ellipsis">{{item.text}}</span>
              </dd>
            </dl>
          </li>
        </ul>
      </div>
    </transition>
    <transition :name="slide.slideName" v-if="Number(slide.type) === 1">
      <div :class="['SLB-box', slide.boxClass]" v-if="slide.box">
        <div class="SLB-title">{{slide.title}}</div>
        <ul class="SLB-list xw-flex xw-flex-column">
          <li v-if="slide.forall.show">
            <h1 :class="['xw-flex xw-flex-align xw-Tfg', String(slide.itemName) === '' ? 'active' : '']" @click="refreshInfo">
              <span class="xw-flex-W1">{{slide.forall.text}}</span>
            </h1>
          </li>
          <li v-for="(item, index) in slide.list">
            <h1 class="xw-flex xw-flex-align xw-Tfg" @click="showChild">
              <span class="xw-flex-W1">{{item.text}}</span>
              <em :class="['far fa-angle-down', String(item.text) === String(slide.itemName) ? 'iconUp' : 'iconDown']"></em>
            </h1>
            <dl class="xw-flex xw-flex-column" :style="[String(item.text) === String(slide.itemName) ? {} : {display: 'none'}]">
              <dd v-for="(son, num) in item.children" :class="['xw-Tfg', String(son.text) === String(slide.childName) ? 'active' : '']" @click="refreshInfo([item.text, son.text])"><span class="xw-flex-W1 xw-ellipsis">{{son.text}}</span></dd>
            </dl>
          </li>
        </ul>
      </div>
    </transition>
    <transition :name="slide.slideName" v-if="Number(slide.type) === 2">
      <div :class="['SLB-box', slide.boxClass]" v-if="slide.box">
        <div class="SLB-title">{{slide.title}}</div>
        <ul class="SLB-more xw-flex xw-flex-column">
          <li v-for="(item, index) in slide.list">
            <h1 class="xw-flex xw-flex-align xw-Tfg" @click="showChild">
              <span class="xw-flex-W1">{{item.text}}</span>
              <em :class="['far fa-angle-down', Number(JSON.stringify(slide.areaback).indexOf(item.value)) !== Number(-1) ? 'iconUp' : 'iconDown'] "></em>
            </h1>
            <dl class="xw-flex xw-flex-column" :style="[Number(JSON.stringify(slide.areaback).indexOf(item.value)) !== Number(-1) ? {} : { display: 'none' }]">
              <dd v-for="(son, num) in item.children" :class="['xw-flex xw-flex-align xw-Tfg', Number(JSON.stringify(slide.areaback).indexOf(son.value)) !== Number(-1) ? 'active' : '']" @click="isCheck($event, item, son)"><span class="xw-flex-W1 xw-ellipsis">{{son.text}}</span><em class="far fa-check"></em></dd>
            </dl>
          </li>
        </ul>
      </div>
    </transition>
    <div class="SLB-boxy" :style="slide.boxTop" v-if="Number(slide.type) === 3">
      <div class="SLB-boxy-con">
        <transition :name="slide.slideName">
          <div :class="[slide.boxClass, 'SLB-boxy-scroll mescroll-touch']" v-if="slide.box">
            <div class="SLB-del xw-flex xw-flex-align xw-flex-justify">
              <span>{{slide.title}}</span>
              <em class="xw-act" @click="close">返回</em>
            </div>
            <ul class="SLB-menu xw-float" v-if="Number(slide.itemId) >= 0">
              <li :class="slide.floatClass" v-if="slide.forall.show"><a :class="['xw-block xw-ellipsis xw-radius-3', Number(slide.itemId) === 0 ? 'active' : '']" :style="slide.align" @click="refreshInfo([slide.forall.value, 0])">{{slide.forall.text}}</a></li>
              <li :class="slide.floatClass" v-for="(item, index) in slide.list"><a :class="['xw-block xw-ellipsis xw-radius-3', Number(item.value) === Number(slide.itemId) ? 'active' : '']" :style="slide.align" @click="refreshInfo([item.value, slide.forall.show ? Number(index + 1) : index])">{{item.text}}</a></li>
            </ul>
            <ul class="SLB-menu xw-float" v-else >
              <li :class="slide.floatClass" v-if="slide.forall.show"><a :class="['xw-block xw-ellipsis xw-radius-3', String(slide.itemName) === '' ? 'active' : '']" :style="slide.align" @click="refreshInfo([slide.forall.value, 0])">{{slide.forall.text}}</a></li>
              <li :class="slide.floatClass" v-for="(item, index) in slide.list"><a :class="['xw-block xw-ellipsis xw-radius-3', String(item.text) === String(slide.itemName) ? 'active' : '']" :style="slide.align" @click="refreshInfo([item.text, slide.forall.show ? Number(index + 1) : index])">{{item.text}}</a></li>
            </ul>
          </div>
        </transition>
      </div>
    </div>
    <transition :name="slide.slideName" v-if="Number(slide.type) === 4">
      <div :class="['SLB-boxp', slide.boxClass]" v-if="slide.box">
        <div class="SLB-boxp-con">
          <div class="SLB-boxp-top">
            <div class="SLB-title">{{slide.title}}</div>
            <div class="SLB-sch xw-flex xw-flex-align" v-if="slide.isSearch">
              <div class="TOP-sch xw-bg-white xw-radius-3 xw-flex-W1 xw-flex xw-flex-align">
                <em class="TOP-L far fa-search"></em>
                <p class="xw-flex-W1"><input class="schText" type="text" placeholder="" v-model.trim="slide.infoSch"/></p>
                <transition name="fade"><em class="fa fa-times-circle" @click="emptyInfo" v-if="slide.infoSch"></em></transition>
                <span class="TOP-btn TOP-R xw-Lfg" @click="getAuditFun(1)">搜索</span>
              </div>
            </div>
          </div>
          <div class="SLB-boxp-body" :style="{ top: slide.changeTop + 'px' }">
            <div class="mescroll-empty" v-if="Number(slide.items.length) === 0"><p class="empty-tip">{{slide.noData}}</p></div>
            <ul class="SLB-spiny xw-flex xw-flex-column" v-else-if="Number(slide.itemId) >= 0">
              <li v-if="slide.forall.show">
                <dl>
                  <dd :class="['xw-ellipsis xw-Tfg', Number(slide.itemId) === 0 ? 'active' : '']" @click="refreshInfo">{{slide.forall.text}}</dd>
                </dl>
              </li>
              <li :class="'scBox_' + index" v-for="(item, index) in slide.items">
                <h1 class="xw-flex xw-flex-align xw-Tfg">{{item.letter}}</h1>
                <dl>
                  <dd v-for="(son, num) in item.children" :class="['xw-ellipsis xw-Tfg', Number(son.value) === Number(slide.itemId) ? 'active' : '']" @click="refreshInfo([son.value])">{{son.text}}</dd>
                </dl>
              </li>
            </ul>
          </div>
        </div>
        <!---->
        <div class="SLB-piny xw-flex xw-flex-column">
          <a class="xw-radius-3 xw-flex xw-flex-center" v-for="(item, index) in slide.items" @click="forScrollTo('.SLB-piny a', index)">{{item.letter}}</a>
        </div>
      </div>
    </transition>
  </div>
</template>

<style scoped>
/* ---- */
.slideBox, .mask { position: fixed; z-index: 10000; top: 0; left: 0; right: 0; bottom: 0; }
.mask { background: rgba(0, 0, 0, 0.5); }
/* ---- */
.SLB-box { position: fixed; z-index: 10000; top: 0; bottom: 0; min-width: 50%; max-width: 80%; background: #ffffff; overflow-y: auto; }
/* ---- */
.SLB-box-left { left: 0; }
.SLB-box-right { right: 0; }
.SLB-box-down { top: 0; right: 0; left: 0; }
/* ---- */
.SLB-title { height: 5rem; line-height: 5rem; text-align: center; font-size: 1.6rem; background: #e7e7e7; }
/* ---- */
.SLB-list li h1 { padding: 0 1rem; height: 4.6rem; font-size: 1.6rem; color: #3388ff; }
.SLB-list li h1 em { font-size: 1.8rem; color: #bbbbbb; }
.SLB-list li h1 em, .SLB-list li h1 span { pointer-events:none; }
.SLB-list li dd { padding: 1rem; color: #3388ff; font-size: 1.6rem; }
.SLB-list li dd:active { color: #ff5722; background: rgba(0, 0, 0, 0.1); }
.SLB-list li h1.active, .SLB-list li dd.active, .SLB-list li dd.active:active { background: #3388ff; color: #ffffff; }
.SLB-list li h1 ~ dl dd { padding: 1rem 1rem 1rem 2rem; color: #111111; font-size: 1.4rem; background: #f6f6f6; }
/* ---- */
.SLB-icon { margin-right: 0.8rem; width: 2rem; height: 2rem; }
/* ---- */
.SLB-more li h1 { padding: 0 1rem; height: 4.6rem; font-size: 1.6rem; color: #3388ff; }
.SLB-more li h1 em { font-size: 1.8rem; color: #bbbbbb; }
.SLB-more li h1 em, .SLB-more li h1 span { pointer-events:none; }
.SLB-more li dd { padding: 1rem 1rem 1rem 2rem; line-height: 2.5rem; color: #111111; background: #f6f6f6; }
.SLB-more li dd em { color: #d7d7d7; }
.SLB-more li dd.active, .SLB-more li dd.active em { color: #ff5722; }
.SLB-more li dd:active, .SLB-more li dd.active:active { color: #ff5722; background: rgba(0, 0, 0, 0.1); }
/* ---- */
.SLB-boxp { position: fixed; z-index: 10000; width: 70%; top: 0; bottom: 0; background: #ffffff; }
.SLB-boxp-con { position: relative; height: 100%; }
.SLB-boxp-top { position: absolute; top: 0; right: 0; left: 0; }
.SLB-boxp-body { position: absolute; right: 0; bottom: 0; left: 0; overflow-y: auto; }
/* ---- */
.SLB-sch { padding: 0 1rem; height: 5rem; background: #f5f5f5; }
/* ---- */
.SLB-spiny li h1 { padding: 0 1rem; height: 3rem; font-size: 1.5rem; color: #888888; background: #f0f0f0; }
.SLB-spiny li dd { padding: 1rem; color: #3388ff; font-size: 1.6rem; }
.SLB-spiny li dd:active { color: #ff5722; background: rgba(0, 0, 0, 0.1); }
.SLB-spiny li dd.active, .SLB-spiny li dd.active:active { background: #3388ff; color: #ffffff; }
/* ---- */
.SLB-boxy { position: fixed; z-index: 10000; left: 0; right: 0; bottom: 0; pointer-events: none; }
.SLB-boxy-con { position: relative; height: 100%; pointer-events: none; }
.SLB-boxy-scroll { position: relative; max-height: 100%; overflow-x: hidden; overflow-y: auto; overflow-scrolling: touch; -webkit-overflow-scrolling: touch; background: #ffffff; pointer-events: auto; }
.SLB-del { height: 5rem; }
.SLB-del span { padding: 0 1.2rem; font-size: 1.7rem; }
.SLB-del em { padding: 1rem 1.2rem; font-size: 1.4rem; }
.SLB-menu { padding: 0 0.5rem 0.5rem; }
.SLB-menu li a { margin: 0 0.5rem 1rem; padding: 1rem; font-size: 1.5rem; background: rgba(0, 0, 0, 0.1); }
.SLB-menu li a:active { background:rgba(0, 0, 0, 0.1); }
.SLB-menu li a.active, .SLB-menu li a.active:active { background: #3388ff; color: #ffffff; }
/* ---- */
.SLB-piny { position: fixed; top: 50%; right: 1rem; transform: translateY(-50%); z-index: 10000; }
.SLB-piny a { width: 2.2rem; height: 2.2rem; text-align: center; overflow: hidden; }
.SLB-piny a.active { color: #ff5722; background: #d7d7d7; }

/* --旋转图标-- */
.iconUp, .iconDown { position: relative; transition: all 300ms; }
.iconUp { transform: rotate(-180deg); -webkit-transform: rotate(-180deg); }
.iconDown { transform: rotate(0deg); -webkit-transform: rotate(0deg); }
/* ---- */
.slideLeft-enter-active, .slideLeft-leave-active { transition: all 300ms; }
.slideLeft-enter-from, .slideLeft-leave-to { transform: translateX(-100%); }
/* ---- */
.slideRight-enter-active, .slideRight-leave-active { transition: all 300ms; }
.slideRight-enter-from, .slideRight-leave-to { transform: translateX(100%); }
/* ---- */
.slideDown-enter-active, .slideDown-leave-active { transition: all 300ms; }
.slideDown-enter-from, .slideDown-leave-to { transform: translateY(-100%); }
</style>
